﻿using Onshi.POS.Modelo.Entidades.Tipos;
using Onshi.POS.Modelo.Enumeradores;
using Onshi.POS.Modelo.Objectos;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Onshi.POS.Modelo.Entidades
{
    [Serializable]
    public class Articulo : EntidadAbstracta<ArticuloCampoPersonalizadoArticulo, CampoPersonalizadoArticulo>
    {
        #region Constructores

        public Articulo() :
            base()
        {
        }

        #endregion

        #region Atributos

        private TipoArticulo tipo;
        private Marca marca;
        private DescuentoRecargoCantidad descuentoRecargoCantidad;
        private TipoComisionArticulo tipoComision;
        private TipoImpuestoArticulo tipoImpuesto;
        private TipoCostoArticulo tipoCosto;
        private DescuentoRecargoFechaHora descuentoRecargoFechaHora;
        private Int32 existenciaMinima;
        private Int32 existenciaMaxima;
        private Decimal costo;
        private Decimal comision;
        private Decimal comisionMaxima;
        private Decimal iva;
        private Decimal impuesto;
        private List<ArticuloListaPrecioVenta> listasPreciosVentas;
        private List<ArticuloListaPrecioCompra> listasPreciosCompras;
        private List<ArticuloVariante> variantes;
        private List<ArticuloExistencia> existencias;
        private List<ArticuloCompuesto> articulosCompuestos;
        private List<Proveedor> proveedores;
        private SubRubroArticulo subRubro;
        private String codigoBarras;

        #endregion

        #region Propiedades

        public String CodigoBarras
        {
            get { return codigoBarras; }
            set { codigoBarras = value; }
        }

        public SubRubroArticulo SubRubro
        {
            get { return subRubro; }
            set { subRubro = value; }
        }

        public String SubRubroNombre
        {
            get { return subRubro.Nombre; }
        }

        public String RubroNombre
        {
            get { return subRubro.RubroNombre; }
        }

        public List<ArticuloCompuesto> ArticulosCompuestos
        {
            get { return articulosCompuestos; }
            set { articulosCompuestos = value; }
        }

        public String ComisionFormato
        {
            get
            {
                var comisionFormato = String.Empty;
                switch ((EnumTiposComisionesArticulos)tipoComision.Id)
                {
                    case EnumTiposComisionesArticulos.PorcentajeVenta:
                    case EnumTiposComisionesArticulos.PorcentajeGanancia:
                        comisionFormato = Formato.Porcentaje(comision);
                        break;
                    case EnumTiposComisionesArticulos.MontoFijo:
                        comisionFormato = Formato.Moneda(comision);
                        break;
                }
                return comisionFormato;
            }
        }

        public String ComisionMaximaFormato
        {
            get
            {
                var comisionMaximaFormato = String.Empty;
                switch ((EnumTiposComisionesArticulos)tipoComision.Id)
                {
                    case EnumTiposComisionesArticulos.PorcentajeVenta:
                    case EnumTiposComisionesArticulos.PorcentajeGanancia:
                        comisionMaximaFormato = Formato.Porcentaje(comisionMaxima);
                        break;
                    case EnumTiposComisionesArticulos.MontoFijo:
                        comisionMaximaFormato = Formato.Moneda(comisionMaxima);
                        break;
                }
                return comisionMaximaFormato;
            }
        }

        public String ImpuestoFormato
        {
            get
            {
                var impuestoFormato = String.Empty;
                switch ((EnumTiposImpuestosArticulos)tipoImpuesto.Id)
                {
                    case EnumTiposImpuestosArticulos.MontoFijo:
                        impuestoFormato = Formato.Moneda(comisionMaxima);
                        break;
                    case EnumTiposImpuestosArticulos.Porcentaje:
                        impuestoFormato = Formato.Porcentaje(comisionMaxima);
                        break;
                }
                return impuestoFormato;
            }
        }

        public String IvaFormato
        {
            get { return Formato.Porcentaje(Iva); }
        }

        public String CostoFormato
        {
            get { return Formato.Moneda(Costo); }
        }

        public String PrecioVentaGeneralFormato
        {
            get { return Formato.Moneda(PrecioVentaGeneral); }
        }

        public Decimal PrecioVentaGeneral
        {
            get
            {
                var precio = 0m;
                var listaPrecio = listasPreciosVentas.SingleOrDefault(x => x.Entidad.Id == (Int32)EnumListasPreciosVentas.General);
                if (listaPrecio != null)
                    precio = listaPrecio.Valor;
                return precio;
            }
        }

        public Boolean TieneProveedores
        {
            get { return proveedores.Count != 0 ? true : false; }
        }

        public List<Proveedor> Proveedores
        {
            get { return proveedores; }
            set { proveedores = value; }
        }

        public String ExistenciaFormato
        {
            get
            {
                var existenciaFormato = String.Empty;
                switch ((EnumTiposArticulos)tipo.Id)
                {
                    case EnumTiposArticulos.Estandar:
                        existenciaFormato = Convert.ToString(Existencia);
                        break;
                }
                return existenciaFormato;
            }
        }

        public String ExistenciaMinimaFormato
        {
            get
            {
                var existenciaMinimaFormato = String.Empty;
                switch ((EnumTiposArticulos)tipo.Id)
                {
                    case EnumTiposArticulos.Estandar:
                        existenciaMinimaFormato = Convert.ToString(existenciaMinima);
                        break;
                }
                return existenciaMinimaFormato;
            }
        }

        public String ExistenciaMaximaFormato
        {
            get
            {
                var existenciaMaximaFormato = String.Empty;
                switch ((EnumTiposArticulos)tipo.Id)
                {
                    case EnumTiposArticulos.Estandar:
                        existenciaMaximaFormato = Convert.ToString(existenciaMaxima);
                        break;
                }
                return existenciaMaximaFormato;
            }
        }

        public String TipoComisionNombre
        {
            get { return tipoComision.Nombre; }
        }

        public String TipoCostoNombre
        {
            get { return tipoCosto.Nombre; }
        }

        public String TipoImpuestoNombre
        {
            get { return tipoImpuesto.Nombre; }
        }

        public String TipoNombre
        {
            get { return tipo.Nombre; }
        }

        public String DescuentoRecargoFechaHoraNombre
        {
            get { return descuentoRecargoFechaHora.Nombre; }
        }

        public String DescuentoRecargoCantidadNombre
        {
            get { return descuentoRecargoCantidad.Nombre; }
        }

        public String MarcaNombre
        {
            get { return marca.Nombre; }
        }

        public Int32 Existencia
        {
            get { return existencias.Sum(x => x.Cantidad); }
        }

        public List<ArticuloExistencia> Existencias
        {
            get { return existencias; }
            set { existencias = value; }
        }

        public List<ArticuloVariante> Variantes
        {
            get { return variantes; }
            set { variantes = value; }
        }

        public List<ArticuloListaPrecioCompra> ListasPreciosCompras
        {
            get { return listasPreciosCompras; }
            set { listasPreciosCompras = value; }
        }

        public List<ArticuloListaPrecioVenta> ListasPreciosVentas
        {
            get { return listasPreciosVentas; }
            set { listasPreciosVentas = value; }
        }

        public TipoArticulo Tipo
        {
            get { return tipo; }
            set { tipo = value; }
        }

        public Decimal Impuesto
        {
            get { return impuesto; }
            set { impuesto = value; }
        }

        public Decimal Iva
        {
            get { return iva; }
            set { iva = value; }
        }

        public Decimal ComisionMaxima
        {
            get { return comisionMaxima; }
            set { comisionMaxima = value; }
        }

        public Decimal Comision
        {
            get { return comision; }
            set { comision = value; }
        }

        public Decimal Costo
        {
            get
            {
                var costoArticulo = Decimal.Zero; ;
                switch ((EnumTiposArticulos)tipo.Id)
                {
                    case EnumTiposArticulos.Estandar:
                    case EnumTiposArticulos.Servicio:
                        costoArticulo = costo;
                        break;
                    case EnumTiposArticulos.Compuesto:
                        if (articulosCompuestos != null)
                            costoArticulo = articulosCompuestos.Sum(x => x.Entidad.Costo * x.Valor);
                        break;
                }
                return costoArticulo;
            }
            set { costo = value; }
        }

        public Int32 ExistenciaMaxima
        {
            get { return existenciaMaxima; }
            set { existenciaMaxima = value; }
        }

        public Int32 ExistenciaMinima
        {
            get { return existenciaMinima; }
            set { existenciaMinima = value; }
        }

        public DescuentoRecargoFechaHora DescuentoRecargoFechaHora
        {
            get { return descuentoRecargoFechaHora; }
            set { descuentoRecargoFechaHora = value; }
        }

        public TipoImpuestoArticulo TipoImpuesto
        {
            get { return tipoImpuesto; }
            set { tipoImpuesto = value; }
        }

        public TipoComisionArticulo TipoComision
        {
            get { return tipoComision; }
            set { tipoComision = value; }
        }

        public DescuentoRecargoCantidad DescuentoRecargoCantidad
        {
            get { return descuentoRecargoCantidad; }
            set { descuentoRecargoCantidad = value; }
        }

        public Marca Marca
        {
            get { return marca; }
            set { marca = value; }
        }

        public TipoCostoArticulo TipoCosto
        {
            get { return tipoCosto; }
            set { tipoCosto = value; }
        }

        #endregion
    }
}
